package com.wss.common.widget.swiperefresh;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.CircularProgressDrawable;
import android.support.v4.widget.ListViewCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Transformation;
import android.widget.AbsListView;
import android.widget.ListView;

/**
 * @author LiBinBin
 * @create 2019/3/12
 * @Describe
 */
@SuppressLint("WrongConstant")
public class SwipeRefreshLayoutNew extends ViewGroup {
    private static final String LOG_TAG = SwipeRefreshLayoutNew.class.getSimpleName();



//    private final int mBottomSpinnerOffsetEnd;
    private View mTarget;
    SwipeRefreshLayoutNew.OnRefreshListener mListener;
    SwipeRefreshLayoutNew.OnBottomRefreshListener mListenerBottom;
    boolean mRefreshing;
    boolean mRefreshingBottom;
    private int mTouchSlop;
    private float mTotalDragDistance;
    private float mTotalUnconsumed;
    private float mTotalUnconsumedBottom;
//    private final NestedScrollingParentHelper mNestedScrollingParentHelper;
//    private final NestedScrollingChildHelper mNestedScrollingChildHelper;
//    private final int[] mParentScrollConsumed;
//    private final int[] mParentOffsetInWindow;
    private boolean mNestedScrollInProgress;
    private int mMediumAnimationDuration;
    int mCurrentTargetOffsetTop;////变化中顶部加载动画的top位置
    int mCurrentTargetOffsetBottom;//变化中底部加载动画的top位置
//    private int windowHeight;
    private float mInitialMotionY;
    private float mInitialMotionYDown;
    private float mInitialDownY;//按下位置y坐标
    private boolean mIsBeingDragged;
    private int mActivePointerId;
    boolean mScale;
    private boolean mReturningToStart;
    private final DecelerateInterpolator mDecelerateInterpolator;
    private static final int[] LAYOUT_ATTRS = new int[]{16842766};
    CircleImageView mCircleView;
    CircleImageView mCircleViewBottom;
    private int mCircleViewIndex;
    /**
     * bottomCircle在视图中的顺序
     */
    private int mCircleViewBottomIndex = -1;
    protected int mFrom;
    float mStartingScale;
    protected int mOriginalOffsetTop;//原始顶部加载动画顶部的top位置
    protected int mOriginalOffsetBottom;//原始底部加载动画顶部的top位置
    int mSpinnerOffsetEnd;
    int mSpinnerBottomOffsetEnd;
    int mCustomSlingshotDistance;
    CircularProgressDrawable mProgress;
    CircularProgressDrawable mProgressBottom;
    private Animation mScaleAnimation;
    private Animation mScaleDownAnimation;
    private Animation mAlphaStartAnimation;
    /**
     * 底部 bottom view的透明度启动动画
     */
    private Animation mAlphaStartAnimationBottom;
    /**
     * 顶部circleView的透明度最大动画
     */
    private Animation mAlphaMaxAnimation;
    /**
     * 底部 bottom view的透明度最大动画
     */
    private Animation mAlphaMaxAnimationBottom;
    private Animation mScaleDownToStartAnimation;
    boolean mNotify;
    /**
     * bottom circle view 标志位
     */
    boolean mNotifyBottom;
    private int mCircleDiameter;//
    boolean mUsingCustomStart;
    private SwipeRefreshLayoutNew.OnChildScrollUpCallback mChildScrollUpCallback;
    private Animation.AnimationListener mRefreshListener;
    private Animation.AnimationListener mRefreshListenerBottom;
    private final Animation mAnimateToCorrectPosition;
    private final Animation mAnimateToCorrectPositionBottom;
    private final Animation mAnimateToStartPosition;
    private final Animation mAnimateToStartPositionBottom;
    //add
    private boolean mBottomIsScrolling;
    /**
     * 第一次测量标志位
     */
    private boolean firstMeasure;

    void reset() {
        this.mCircleView.clearAnimation();
        this.mCircleViewBottom.clearAnimation();
        this.mProgress.stop();
        this.mCircleView.setVisibility(8);
        this.mCircleViewBottom.setVisibility(8);
        this.mProgressBottom.stop();
        this.setColorViewAlpha(255);
        if (this.mScale) {
            this.setAnimationProgress(0.0F);
            this.setAnimationProgressBottom(0.0F);
        } else {
            this.setTargetOffsetTopAndBottom(this.mOriginalOffsetTop - this.mCurrentTargetOffsetTop);
            this.setTargetOffsetTopAndBottomForBottom( this.mOriginalOffsetBottom -  this.mCurrentTargetOffsetBottom);
        }

        this.mCurrentTargetOffsetTop = this.mCircleView.getTop();
        this.mOriginalOffsetBottom = this.mCircleViewBottom.getTop();
    }

    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        if (!enabled) {
            this.reset();
        }

    }

    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        this.reset();
    }

    private void setColorViewAlpha(int targetAlpha) {
        this.mCircleView.getBackground().setAlpha(targetAlpha);
        this.mProgress.setAlpha(targetAlpha);

        this.mCircleViewBottom.getBackground().setAlpha(targetAlpha);
        this.mProgressBottom.setAlpha(targetAlpha);
    }

//    public void setProgressViewOffset(boolean scale, int start, int end) {
//        this.mScale = scale;
//        this.mOriginalOffsetTop = start;
//        this.mSpinnerOffsetEnd = end;
//        this.mUsingCustomStart = true;
//        this.reset();
//        this.mRefreshing = false;
//        this.mRefreshingBottom = false;
//    }

//    public int getProgressViewStartOffset() {
//        return this.mOriginalOffsetTop;
//    }
//
//    public int getProgressViewEndOffset() {
//        return this.mSpinnerOffsetEnd;
//    }
//
//    public void setProgressViewEndTarget(boolean scale, int end) {
//        this.mSpinnerOffsetEnd = end;
//        this.mScale = scale;
//        this.mCircleView.invalidate();
//    }
//
//    public void setSlingshotDistance(@Px int slingshotDistance) {
//        this.mCustomSlingshotDistance = slingshotDistance;
//    }

    public void setSize(int size) {
        if (size == 0 || size == 1) {
            DisplayMetrics metrics = this.getResources().getDisplayMetrics();
            if (size == 0) {
                this.mCircleDiameter = (int) (56.0F * metrics.density);
            } else {
                this.mCircleDiameter = (int) (40.0F * metrics.density);
            }

            this.mCircleView.setImageDrawable(null);
            this.mCircleViewBottom.setImageDrawable(null);
            this.mProgress.setStyle(size);
            this.mCircleView.setImageDrawable(this.mProgress);
            this.mProgressBottom.setStyle(size);
            this.mCircleViewBottom.setImageDrawable(this.mProgressBottom);
        }
    }

    public SwipeRefreshLayoutNew(@NonNull Context context) {
        this(context, (AttributeSet) null);
    }

    @SuppressLint("ResourceType")
    public SwipeRefreshLayoutNew(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.mRefreshing = false;
        this.mRefreshingBottom = false;
        this.mTotalDragDistance = -1.0F;
//        this.mParentScrollConsumed = new int[2];
//        this.mParentOffsetInWindow = new int[2];
        this.mActivePointerId = -1;
        this.mCircleViewIndex = -1;
        this.mRefreshListener = new Animation.AnimationListener() {
            public void onAnimationStart(Animation animation) {
            }

            public void onAnimationRepeat(Animation animation) {
            }

            public void onAnimationEnd(Animation animation) {

                if (SwipeRefreshLayoutNew.this.mRefreshing) {
                    SwipeRefreshLayoutNew.this.mProgress.setAlpha(255);
                    SwipeRefreshLayoutNew.this.mProgress.start();
                    if (SwipeRefreshLayoutNew.this.mNotify && SwipeRefreshLayoutNew.this.mListener != null) {
                        SwipeRefreshLayoutNew.this.mListener.onRefresh();
                    }

                    SwipeRefreshLayoutNew.this.mCurrentTargetOffsetTop = SwipeRefreshLayoutNew.this.mCircleView.getTop();
                 } else {
                    SwipeRefreshLayoutNew.this.reset();
                }

            }
        };


        /**刷新动画监听，在动画结束的时候判断，如果还在刷新就继续显示circle，*/
        this.mRefreshListenerBottom = new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (SwipeRefreshLayoutNew.this.mRefreshingBottom) {
                    // Make sure the progress view is fully visible
                    SwipeRefreshLayoutNew.this.mProgressBottom.setAlpha(255);
                    SwipeRefreshLayoutNew.this.mProgressBottom.start();
                    if (SwipeRefreshLayoutNew.this.mNotifyBottom) {
                        if (SwipeRefreshLayoutNew.this.mListenerBottom != null) {
                            SwipeRefreshLayoutNew.this.mListenerBottom.onBottomRefresh();
                        } else {
                        }
                    }
                    SwipeRefreshLayoutNew.this.mCurrentTargetOffsetBottom = SwipeRefreshLayoutNew.this.mCircleViewBottom.getTop();
                } else {
                    SwipeRefreshLayoutNew.this.reset();
                }
            }
        };


        this.mAnimateToCorrectPosition = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                int endTarget;
                if (!SwipeRefreshLayoutNew.this.mUsingCustomStart) {
                    endTarget = SwipeRefreshLayoutNew.this.mSpinnerOffsetEnd - Math.abs(SwipeRefreshLayoutNew.this.mOriginalOffsetTop);
                } else {
                    endTarget = SwipeRefreshLayoutNew.this.mSpinnerOffsetEnd;
                }

                int targetTop = SwipeRefreshLayoutNew.this.mFrom + (int) ((float) (endTarget - SwipeRefreshLayoutNew.this.mFrom) * interpolatedTime);

                int offset = targetTop - SwipeRefreshLayoutNew.this.mCircleView.getTop();
               SwipeRefreshLayoutNew.this.setTargetOffsetTopAndBottom(offset);
                SwipeRefreshLayoutNew.this.mProgress.setArrowScale(1.0F - interpolatedTime);
            }
        };
        /**刷新的动画，将circle从mFrom移动到
         *中间然后滑动
         * Bottom
         * */
        this.mAnimateToCorrectPositionBottom = new Animation() {
            @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                int targetTop = 0;
                int endTarget = 0;
                if (!SwipeRefreshLayoutNew.this.mUsingCustomStart) {//false
                    endTarget =  SwipeRefreshLayoutNew.this.mSpinnerBottomOffsetEnd+SwipeRefreshLayoutNew.this.mCircleDiameter;//
                } else {
                    endTarget = SwipeRefreshLayoutNew.this.mSpinnerBottomOffsetEnd;
                }
                targetTop = (SwipeRefreshLayoutNew.this.mFrom + (int) ((endTarget - SwipeRefreshLayoutNew.this.mFrom) * interpolatedTime));//一开始我这里有疑惑，但是后来才想到interpolatedTime是0.x的。也就相当于百分比
                int offset = targetTop - SwipeRefreshLayoutNew.this.mCircleViewBottom.getBottom();
                //  setTargetOffsetTopAndBottom(offset, false /* requires update */);
                SwipeRefreshLayoutNew.this.setTargetOffsetTopAndBottomForBottom(offset);
                SwipeRefreshLayoutNew.this.mProgressBottom.setArrowScale(1 - interpolatedTime);
            }
        };
        this.mAnimateToStartPosition = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.moveToStart(interpolatedTime);
            }
        };
        this.mAnimateToStartPositionBottom = new Animation() {
            @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.moveToEnd(interpolatedTime);
            }
        };
        this.mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        this.mMediumAnimationDuration = this.getResources().getInteger(17694721);
        this.setWillNotDraw(false);
        this.mDecelerateInterpolator = new DecelerateInterpolator(2.0F);
        DisplayMetrics metrics = this.getResources().getDisplayMetrics();
        this.mCircleDiameter = (int) (40.0F * metrics.density);
        this.createProgressView();
        this.setChildrenDrawingOrderEnabled(true);
        this.mSpinnerOffsetEnd = (int) (64.0F * metrics.density);

        this.mTotalDragDistance = (float) this.mSpinnerOffsetEnd;
//        this.mNestedScrollingParentHelper = new NestedScrollingParentHelper(this);
//        this.mNestedScrollingChildHelper = new NestedScrollingChildHelper(this);
//        this.setNestedScrollingEnabled(true);
        this.mOriginalOffsetTop = this.mCurrentTargetOffsetTop = -this.mCircleDiameter;
        this.mOriginalOffsetBottom = this.mCurrentTargetOffsetBottom;
        this.moveToStart(1.0F);
        this.moveToEnd(1.0F);
//        TypedArray a = context.obtainStyledAttributes(attrs, LAYOUT_ATTRS);
//        this.setEnabled(a.getBoolean(0, true));
//        a.recycle();


    }

//    protected int getChildDrawingOrder(int childCount, int i) {
//        if (this.mCircleViewIndex < 0) {
//            return i;
//        } else if (i == childCount - 1) {
//            return this.mCircleViewIndex;
//        } else {
//            return i >= this.mCircleViewIndex ? i + 1 : i;
//        }
//    }

    private void createProgressView() {
        this.mCircleView = new CircleImageView(this.getContext(), -328966);
        this.mCircleViewBottom = new CircleImageView(getContext(), -328966);
        this.mProgress = new CircularProgressDrawable(this.getContext());
        this.mProgress.setStyle(1);
        this.mCircleView.setImageDrawable(this.mProgress);
        this.mCircleView.setVisibility(8);
        this.addView(this.mCircleView);
        this.mProgressBottom = new CircularProgressDrawable(getContext());
        this.mProgressBottom.setStyle(1);
        this.mCircleViewBottom.setImageDrawable(this.mProgressBottom);
        this.mCircleViewBottom.setVisibility(8);
        this.addView(this.mCircleViewBottom);
    }

    public void setOnRefreshListener(@Nullable SwipeRefreshLayoutNew.OnRefreshListener listener) {
        this.mListener = listener;
    }

    public void setOnBottomRefreshListenrer(@Nullable SwipeRefreshLayoutNew.OnBottomRefreshListener listener) {
        mListenerBottom = listener;
    }

    public void setRefreshing(boolean refreshing) {
        if (refreshing && this.mRefreshing != refreshing) {
            this.mRefreshing = refreshing;
            int endTarget;
            if (!this.mUsingCustomStart) {
                endTarget = this.mSpinnerOffsetEnd + this.mOriginalOffsetTop;
            } else {
                endTarget = this.mSpinnerOffsetEnd;
            }
            this.setTargetOffsetTopAndBottom(endTarget - this.mCurrentTargetOffsetTop);
            this.mNotify = false;
            this.startScaleUpAnimation(this.mRefreshListener);
        } else {
            this.setRefreshing(refreshing, false);
        }

    }

    public void setBottomRefreshing(boolean refreshing) {
        if (refreshing && this.mRefreshingBottom != refreshing) {
            // scale and show
            this.mRefreshingBottom = refreshing;
            int endTarget = 0;
            if (!this.mUsingCustomStart) {
                endTarget = (int) (this.mSpinnerOffsetEnd - this.mCircleDiameter );
            } else {
                endTarget = this.mSpinnerOffsetEnd;
            }
            this.setTargetOffsetTopAndBottomForBottom(-(endTarget + this.mCircleDiameter));
            this.mNotifyBottom = false;
            this.startScaleUpAnimationBottom(this.mRefreshListenerBottom);
        } else {
            this.setRefreshingBottom(refreshing, false /* notify */);
        }
    }

    private void startScaleUpAnimation(Animation.AnimationListener listener) {
        this.mCircleView.setVisibility(0);
        this.mProgress.setAlpha(255);
        this.mScaleAnimation = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.setAnimationProgress(interpolatedTime);
            }
        };
        this.mScaleAnimation.setDuration((long) this.mMediumAnimationDuration);
        if (listener != null) {
            this.mCircleView.setAnimationListener(listener);
        }

        this.mCircleView.clearAnimation();
        this.mCircleView.startAnimation(this.mScaleAnimation);
    }

    /**
     * 开始底部 CircleView的动画
     */
    private void startScaleUpAnimationBottom(Animation.AnimationListener listener) {
        this.mCircleViewBottom.setVisibility(View.VISIBLE);
        this.mProgressBottom.setAlpha(255);
        this.mScaleAnimation = new Animation() {
            @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.setAnimationProgressBottom(interpolatedTime);//interpolatedTime 从小到大，0.0-1
            }
        };
        this.mScaleAnimation.setDuration(this.mMediumAnimationDuration);
        if (listener != null) {
            this.mCircleViewBottom.setAnimationListener(listener);
        }
        this.mCircleViewBottom.clearAnimation();
        this.mCircleViewBottom.startAnimation(this.mScaleAnimation);
    }

    /**
     * Pre API 11, alpha is used to make the progress circle appear instead of scale.
     * 这里是判断机型版本有没有大于安卓3.0
     * 小于返回true
     */
//    private boolean isAlphaUsedForScale() {
//        return android.os.Build.VERSION.SDK_INT < 11;//11 是Android3.0
//    }

    void setAnimationProgress(float progress) {
        this.mCircleView.setScaleX(progress);
        this.mCircleView.setScaleY(progress);
    }

    void setAnimationProgressBottom(float progress) {
        this.mCircleViewBottom.setScaleX(progress);
        this.mCircleViewBottom.setScaleY(progress);


    }

    private void setRefreshing(boolean refreshing, boolean notify) {
        if (this.mRefreshing != refreshing) {
            this.mNotify = notify;
            this.ensureTarget();
            this.mRefreshing = refreshing;
            if (this.mRefreshing) {
                this.animateOffsetToCorrectPosition(this.mCurrentTargetOffsetTop, this.mRefreshListener);
            } else {
                this.startScaleDownAnimation(this.mRefreshListener);
            }
        }

    }

    /**
     * 设置refreshing的状态，如果不相应就相应的改变，应该是为了设置刷不刷新
     */
    private void setRefreshingBottom(boolean refreshing, final boolean notify) {
        if (this.mRefreshingBottom != refreshing) {
            this.mNotifyBottom = notify;
            ensureTarget();
            this.mRefreshingBottom = refreshing;
            if (this.mRefreshingBottom) {//如果标志位正确，就启动刷新动画，将circle一步步移到中间那个位置
                this.animateOffsetToCorrectPositionBottom(this.mCurrentTargetOffsetBottom, this.mRefreshListenerBottom);//

            } else {
                this.startScaleDownAnimationBottom(this.mRefreshListenerBottom);
            }
        }
    }

    void startScaleDownAnimation(Animation.AnimationListener listener) {
        this.mScaleDownAnimation = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.setAnimationProgress(1.0F - interpolatedTime);
            }
        };
        this.mScaleDownAnimation.setDuration(150L);
        this.mCircleView.setAnimationListener(listener);
        this.mCircleView.clearAnimation();
        this.mCircleView.startAnimation(this.mScaleDownAnimation);
    }

    /**
     * 开始mScaleDownAnimation动画，还有对于circle进程的改变
     * 就是在你手指拖动的过程中改变
     * <p>
     * bottomn
     */
    void startScaleDownAnimationBottom(Animation.AnimationListener listener) {
        this.mScaleDownAnimation = new Animation() {
            @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.setAnimationProgressBottom(1 - interpolatedTime);//倒着转？
            }
        };
        this.mScaleDownAnimation.setDuration(150);
        this.mCircleViewBottom.setAnimationListener(listener);
        this.mCircleViewBottom.clearAnimation();
        this.mCircleViewBottom.startAnimation(this.mScaleDownAnimation);
    }

    private void startProgressAlphaStartAnimation() {
        this.mAlphaStartAnimation = this.startAlphaAnimation(this.mProgress.getAlpha(), 76);
    }

    /**
     * 开始透明度的变化，最终76
     * <p>for bottom CircleView</p>
     */
    private void startProgressAlphaStartAnimationBottom() {
        this.mAlphaStartAnimationBottom = this.startAlphaAnimationBottom(mProgressBottom.getAlpha(), 76);
    }

    /**
     * 开启到最大的透明度，255
     * <p>for top CircleView</p>
     */
    private void startProgressAlphaMaxAnimationBottom() {
        this.mAlphaMaxAnimationBottom = this.startAlphaAnimationBottom(mProgressBottom.getAlpha(), 255);
    }


    private void startProgressAlphaMaxAnimation() {
        this.mAlphaMaxAnimation = this.startAlphaAnimation(this.mProgress.getAlpha(), 255);
    }

    private Animation startAlphaAnimation(final int startingAlpha, final int endingAlpha) {
        Animation alpha = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.mProgress.setAlpha((int) ((float) startingAlpha + (float) (endingAlpha - startingAlpha) * interpolatedTime));
            }
        };
        alpha.setDuration(300L);
        this.mCircleView.setAnimationListener((Animation.AnimationListener) null);
        this.mCircleView.clearAnimation();
        this.mCircleView.startAnimation(alpha);
        return alpha;
    }

    /**
     * 透明度动画。两个参数分别是开始透明度和结束，这样可能效果不会太突兀？
     * <p>for top circle view</p>
     */
    private Animation startAlphaAnimationBottom(final int startingAlpha, final int endingAlpha) {
        if (this.mScale ) {
            return null;
        }
        Animation alpha = new Animation() {
            @Override
            public void applyTransformation(float interpolatedTime, Transformation t) {
                SwipeRefreshLayoutNew.this.mProgressBottom.setAlpha(
                        (int) (startingAlpha + ((endingAlpha - startingAlpha) * interpolatedTime)));
            }
        };
        alpha.setDuration(300);
        // Clear out the previous animation listeners.
        this.mCircleViewBottom.setAnimationListener(null);
        this.mCircleViewBottom.clearAnimation();
        this.mCircleViewBottom.startAnimation(alpha);
        return alpha;
    }

    /**
     * @deprecated
     */
    @Deprecated
    public void setProgressBackgroundColor(int colorRes) {
        this.setProgressBackgroundColorSchemeResource(colorRes);
    }

    public void setProgressBackgroundColorSchemeResource(@ColorRes int colorRes) {
        this.setProgressBackgroundColorSchemeColor(ContextCompat.getColor(this.getContext(), colorRes));
    }

    public void setProgressBackgroundColorSchemeColor(@ColorInt int color) {
        this.mCircleView.setBackgroundColor(color);
    }

    /**
     * @deprecated
     */
    @Deprecated
    public void setColorScheme(@ColorRes int... colors) {
        this.setColorSchemeResources(colors);
    }

    public void setColorSchemeResources(@ColorRes int... colorResIds) {
        Context context = this.getContext();
        int[] colorRes = new int[colorResIds.length];

        for (int i = 0; i < colorResIds.length; ++i) {
            colorRes[i] = ContextCompat.getColor(context, colorResIds[i]);
        }

        this.setColorSchemeColors(colorRes);
    }

    public void setColorSchemeColors(@ColorInt int... colors) {
        this.ensureTarget();
        this.mProgress.setColorSchemeColors(colors);
    }
    /**
     * @deprecated
     */
    @Deprecated
    public void setBottomColorScheme(@ColorRes int... colors) {
        this.setBottomColorSchemeResources(colors);
    }

    public void setBottomColorSchemeResources(@ColorRes int... colorResIds) {
        Context context = this.getContext();
        int[] colorRes = new int[colorResIds.length];

        for (int i = 0; i < colorResIds.length; ++i) {
            colorRes[i] = ContextCompat.getColor(context, colorResIds[i]);
        }

        this.setBottomColorSchemeColors(colorRes);
    }
    /**
     * 设置底部circle加载颜色
     */
    public void setBottomColorSchemeColors(int... colors) {
        ensureTarget();
        this.mProgressBottom.setColorSchemeColors(colors);
    }

    public boolean isRefreshing() {
        return this.mRefreshing;
    }

    public boolean isRefreshingBottom() {
        return this.mRefreshingBottom;
    }

    private void ensureTarget() {
        if (this.mTarget == null) {
            for (int i = 0; i < this.getChildCount(); ++i) {
                View child = this.getChildAt(i);
                if (!child.equals(mCircleView) && !child.equals(mCircleViewBottom)) {
                    this.mTarget = child;
                    break;
                }
            }
        }

    }

    public void setDistanceToTriggerSync(int distance) {
        this.mTotalDragDistance = (float) distance;
    }

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int width = this.getMeasuredWidth();
        int height = this.getMeasuredHeight();
        this.mInitialMotionYDown = bottom;
        if(firstMeasure){//*底部动画移动时mCurrentTargetOffsetBottom随时改变，方法时会覆盖掉mCurrentTargetOffsetBottom的值导致无法滑动，故区分是否第一次调用onLayout
            this.mCurrentTargetOffsetBottom = bottom;
            firstMeasure=false;
        }

        this.mOriginalOffsetBottom = bottom;
        this.mSpinnerBottomOffsetEnd = bottom - this.mSpinnerOffsetEnd;
        if (this.getChildCount() != 0) {
            if (this.mTarget == null) {
                this.ensureTarget();
            }

            if (this.mTarget != null) {
                View child = this.mTarget;
                int childLeft = this.getPaddingLeft();
                int childTop = this.getPaddingTop();
                int childWidth = width - this.getPaddingLeft() - this.getPaddingRight();
                int childHeight = height - this.getPaddingTop() - this.getPaddingBottom();
                child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
                int circleWidth = this.mCircleView.getMeasuredWidth();
                int circleHeight = this.mCircleView.getMeasuredHeight();
                this.mCircleView.layout(width / 2 - circleWidth / 2, this.mCurrentTargetOffsetTop, width / 2 + circleWidth / 2, this.mCurrentTargetOffsetTop + circleHeight);
                int circleBottomWidth = mCircleViewBottom.getMeasuredWidth();
                int circleBottomHeight = mCircleViewBottom.getMeasuredHeight();
                this.mCircleViewBottom.layout((width / 2 - circleBottomWidth / 2), this.mCurrentTargetOffsetBottom,
                        (width / 2 + circleBottomWidth / 2), this.mCurrentTargetOffsetBottom +circleBottomHeight);
            }
        }
    }

    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (this.mTarget == null) {
            this.ensureTarget();
        }

        if (this.mTarget != null) {
            this.mTarget.measure(MeasureSpec.makeMeasureSpec(this.getMeasuredWidth() - this.getPaddingLeft() - this.getPaddingRight(), 1073741824), MeasureSpec.makeMeasureSpec(this.getMeasuredHeight() - this.getPaddingTop() - this.getPaddingBottom(), 1073741824));
            this.mCircleView.measure(MeasureSpec.makeMeasureSpec(this.mCircleDiameter, 1073741824), MeasureSpec.makeMeasureSpec(this.mCircleDiameter, 1073741824));
            this.mCircleViewIndex = -1;

            for (int index = 0; index < this.getChildCount(); ++index) {
                if (this.getChildAt(index) == this.mCircleView) {
                    this.mCircleViewIndex = index;
                    break;
                }
            }
            this.mCircleViewBottom.measure(MeasureSpec.makeMeasureSpec(this.mCircleDiameter, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(this.mCircleDiameter, MeasureSpec.EXACTLY));
            this.mCircleViewBottomIndex = -1;
            for (int index = 0; index < getChildCount(); index++) {
                if (getChildAt(index) == this.mCircleViewBottom) {
                    this.mCircleViewBottomIndex = index;
                    break;
                }
            }
        }
    }

    public int getProgressCircleDiameter() {
        return this.mCircleDiameter;
    }

    public boolean canChildScrollUp() {
        if (this.mChildScrollUpCallback != null) {
            return this.mChildScrollUpCallback.canChildScrollUp(this, this.mTarget);
        } else {
            return this.mTarget instanceof ListView ? ListViewCompat.canScrollList((ListView) this.mTarget, -1) : this.mTarget.canScrollVertically(-1);
        }
    }


    //判断是否可以上拉
    public boolean canChildScrollDown() {
        if (Build.VERSION.SDK_INT < 14) {
            if (mTarget instanceof AbsListView) {
                final AbsListView absListView = (AbsListView) mTarget;
                // AppLog.e(absListView.getFirstVisiblePosition()+"  :   "+absListView.getChildAt(absListView.getChildCount()-1).getBottom()+"  :   "+absListView.getPaddingBottom());
                return absListView.getChildCount() > 0
                        && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
                        .getTop() < absListView.getPaddingTop());
            } else {
                return mTarget.getScrollY() > 0;
            }
        } else {
            return ViewCompat.canScrollVertically(mTarget, 1);
        }
    }


    public void setOnChildScrollUpCallback(@Nullable SwipeRefreshLayoutNew.OnChildScrollUpCallback callback) {
        this.mChildScrollUpCallback = callback;
    }

    public boolean onInterceptTouchEvent(MotionEvent ev) {
        this.ensureTarget();
        int action = ev.getActionMasked();
        if (this.mReturningToStart && action == 0) {
            this.mReturningToStart = false;
        }
        Log.v("load","canChildScrollUp"+canChildScrollUp());
        Log.v("load","canChildScrollDown"+canChildScrollDown());
        //满足条件拦截，执行onTouch方法，开始动画
        if (this.isEnabled() && !this.mReturningToStart && (!canChildScrollUp() || !canChildScrollDown()) && !this.mRefreshing && !this.mRefreshingBottom && !this.mNestedScrollInProgress) {
            int pointerIndex;
            switch (action) {
                case 0://ACTION_DOWN
                    if (!canChildScrollUp()) {
                        this.setTargetOffsetTopAndBottom(this.mOriginalOffsetTop - this.mCircleView.getTop());
                    }
                    if (!canChildScrollDown()) {
                        this.setTargetOffsetTopAndBottomForBottom((this.mOriginalOffsetBottom + this.mCircleDiameter) - this.mCircleViewBottom.getBottom());
                    }
                    this.mActivePointerId = ev.getPointerId(0);
                    this.mIsBeingDragged = false;
                    pointerIndex = ev.findPointerIndex(this.mActivePointerId);
                    if (pointerIndex < 0) {
                        return false;
                    }

                    this.mInitialDownY = ev.getY(pointerIndex);
                    break;
                case 1:
                case 3:
                    this.mIsBeingDragged = false;
                    this.mActivePointerId = -1;
                    break;
                case 2://ACTION_MOVE
                    if (this.mActivePointerId == -1) {
                        return false;
                    }

                    pointerIndex = ev.findPointerIndex(this.mActivePointerId);
                    if (pointerIndex < 0) {
                        return false;
                    }

                    float y = ev.getY(pointerIndex);
                    this.startDragging(y);
                case 4:
                case 5:
                default:
                    break;
                case 6:
                    this.onSecondaryPointerUp(ev);
            }

            return this.mIsBeingDragged;
        } else {
            return false;
        }
    }

//    public void requestDisallowInterceptTouchEvent(boolean b) {
////        if ((Build.VERSION.SDK_INT >= 21 || !(this.mTarget instanceof AbsListView)) && (this.mTarget == null || ViewCompat.isNestedScrollingEnabled(this.mTarget))) {
////            super.requestDisallowInterceptTouchEvent(b);
////        }
//
//    }
//
//    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
//        return this.isEnabled() && !this.mReturningToStart && !this.mRefreshing && !this.mRefreshingBottom && (nestedScrollAxes & 2) != 0;
//    }
//
//    public void onNestedScrollAccepted(View child, View target, int axes) {
////        this.mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes);
////        this.startNestedScroll(axes & 2);
////        this.mTotalUnconsumed = 0.0F;
////        this.mNestedScrollInProgress = true;
//    }
//
//    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
////        Log.v("funtion","onNestedPreScroll");
////        if (dy > 0 && this.mTotalUnconsumed > 0.0F&& !mRefreshingBottom) {//向下拖dy小于0，所以这是为了处理拖circle到一半然后又缩回去的情况
////            if ((float) dy > this.mTotalUnconsumed) {//拖动的很多，大于未消费的
////                consumed[1] = dy - (int) this.mTotalUnconsumed;
////                this.mTotalUnconsumed = 0.0F;
////            } else {//拖动一点，我们全部用给自己
////                this.mTotalUnconsumed -= (float) dy;
////                consumed[1] = dy;
////            }
////
////            this.moveSpinner(this.mTotalUnconsumed);
////        }
////
////        //处理底部的,圆圈已经出来了之后它又向下拖
////        if(dy<0 && this.mTotalUnconsumedBottom > 0 && !this.mRefreshing)
////        {
////            Log.e("fish","dy<0 && mTotalUnconsumedBottom > 0+++dy=="+dy+",mTotalUnconsumedBottom=="+mTotalUnconsumedBottom);
////            if(-dy>this.mTotalUnconsumedBottom)//如果拖动的很多，就先给圆圈，然后还给子控件
////            {
////                consumed[1]= -(int) this.mTotalUnconsumedBottom;
////                this.mTotalUnconsumedBottom = 0;
////                this.mBottomIsScrolling = false;
////            }else{//否则，先给父控件
////                this.mTotalUnconsumedBottom +=dy;
////                consumed[1]=dy;//原来传回去的是正数，结果越滑越快。。。改成负数之后就对了，开心
////            }
////            this.moveBottomSpinner(mTotalUnconsumedBottom);
////        }
////
////        if (this.mUsingCustomStart && dy > 0 && this.mTotalUnconsumed == 0.0F && Math.abs(dy - consumed[1]) > 0) {
////            this.mCircleView.setVisibility(8);
////        }
////
////        int[] parentConsumed = this.mParentScrollConsumed;
////        if (this.dispatchNestedPreScroll(dx - consumed[0], dy - consumed[1], parentConsumed, (int[]) null)) {
////            consumed[0] += parentConsumed[0];
////            consumed[1] += parentConsumed[1];
////        }
//
//    }
//
//    public int getNestedScrollAxes() {
//        return this.mNestedScrollingParentHelper.getNestedScrollAxes();
//    }
//
//    public void onStopNestedScroll(View target) {
////        this.mNestedScrollingParentHelper.onStopNestedScroll(target);
////        this.mNestedScrollInProgress = false;
////        if (this.mTotalUnconsumed > 0.0F&& !mRefreshing) {
////            this.finishSpinner(this.mTotalUnconsumed);
////            this.mTotalUnconsumed = 0.0F;
////        }
////        if(this.mTotalUnconsumedBottom > 0 && !mRefreshingBottom)
////        {
////            Log.e("fish","onStopNestedScroll,mTotalUnconsumedBottom > 0");
////            this.finishSpinnerBottom(this.mTotalUnconsumedBottom);
////            this.mTotalUnconsumedBottom = 0;
//////            this.mBottomIsScrolling = false;
////        }
////        this.stopNestedScroll();
//    }
//
//    public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
////        this.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, this.mParentOffsetInWindow);
////        int dy = dyUnconsumed + this.mParentOffsetInWindow[1];
////        if (dy < 0 && !this.canChildScrollUp() && !mRefreshing) {
////            this.mTotalUnconsumed += (float) Math.abs(dy);
////            this.moveSpinner(this.mTotalUnconsumed);
////        }else if(dy > 0 && ! this.canChildScrollDown() && ! this.mRefreshingBottom) //向上拉
////        {
////            this. mTotalUnconsumedBottom +=dy;
////            this.moveBottomSpinner(mTotalUnconsumedBottom);
//////            this.mBottomIsScrolling = true;
////        }
//
//    }
//
//    public void setNestedScrollingEnabled(boolean enabled) {
//        this.mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
//    }
//
//    public boolean isNestedScrollingEnabled() {
//        return this.mNestedScrollingChildHelper.isNestedScrollingEnabled();
//    }
//
//    public boolean startNestedScroll(int axes) {
//        return this.mNestedScrollingChildHelper.startNestedScroll(axes);
//    }
//
//    public void stopNestedScroll() {
//        this.mNestedScrollingChildHelper.stopNestedScroll();
//    }
//
//    public boolean hasNestedScrollingParent() {
//        return this.mNestedScrollingChildHelper.hasNestedScrollingParent();
//    }
//
//    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
//        return this.mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
//    }
//
//    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
////        //先拦截
////        if(this.mBottomIsScrolling && this.mTotalUnconsumedBottom>0 &&dy<0)//设置成功！但是子view还在动
////        {
////            Log.e("fish","父：dispatchNestedPreScroll,mTotalUnconsumedBottom="+mTotalUnconsumedBottom+",dy=="+dy);
////            if(-dy>=this.mTotalUnconsumedBottom)//向下拖动很大
////            {
////                this.moveBottomSpinner(this.mTotalUnconsumedBottom);
////            }else {
////                this.moveBottomSpinner(-dy);
////                this.mTotalUnconsumedBottom -= dy;
////                dy = 0;
////            }
////        }
//        return this.mNestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
//    }
//
//    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
//        return this.dispatchNestedPreFling(velocityX, velocityY);
//    }
//
//    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
//        return this.dispatchNestedFling(velocityX, velocityY, consumed);
//    }
//
//    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
//        return this.mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
//    }
//
//    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
//        return this.mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
//    }

    private boolean isAnimationRunning(Animation animation) {
        return animation != null && animation.hasStarted() && !animation.hasEnded();
    }

    /**
     * 进行实际circle的滑动绘制，包括颜色等设置
     *
     * @param overscrollBottom 滑动的绝对值
     */
    private void moveBottomSpinner(float overscrollBottom) {
        this.mProgressBottom.setArrowEnabled(true);
        float originalDragPercent = overscrollBottom / this.mTotalDragDistance;
        float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
        float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3;//这个不理解
        float extraOS = Math.abs(overscrollBottom) - this.mTotalDragDistance;//这样不就是负的吗//就是负的//可以是正的
        float slingshotDist = this.mUsingCustomStart ? (this.mOriginalOffsetBottom + this.mCircleDiameter) - this.mSpinnerBottomOffsetEnd
                : this.mSpinnerOffsetEnd;///mSpinnerOffsetEnd 默认是拉到最底的可能位置 ，和mTotalDragDistance一开始初始化是相同的
        float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2)
                / slingshotDist);
        float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
                (tensionSlingshotPercent / 4), 2)) * 2f;//tensionSlingshotPercent = x ,x/4-(x/4)^2,再*2，最多0.5
        float extraMove = (slingshotDist) * tensionPercent * 2;//这个是模拟后来的拖动，最多slingshotDist

        int targetY = this.mOriginalOffsetBottom - (int) ((slingshotDist * dragPercent) + extraMove);
        // where 1.0f is a full circle
        if (this.mCircleViewBottom.getVisibility() != View.VISIBLE) {
            this.mCircleViewBottom.setVisibility(View.VISIBLE);
        }
        if (!mScale) {
            this.mCircleViewBottom.setScaleX(1.0F);
            this.mCircleViewBottom.setScaleY(1.0F);
        }

        if (mScale) {
            setAnimationProgressBottom(Math.min(1f, overscrollBottom / this.mTotalDragDistance));
        }
        if (overscrollBottom < this.mTotalDragDistance) {
            if (mProgressBottom.getAlpha() > 76
                    && !isAnimationRunning(mAlphaStartAnimationBottom)) {
                this.startProgressAlphaStartAnimationBottom();
            }
        } else {
            if (mProgressBottom.getAlpha() < 255 && !isAnimationRunning(mAlphaMaxAnimationBottom)) {
                this.startProgressAlphaMaxAnimationBottom();
            }
        }
        float strokeStart = adjustedPercent * .8f;
        this.mProgressBottom.setStartEndTrim(0f, Math.min(0.8F, strokeStart));//Trim 修剪
        this.mProgressBottom.setArrowScale(Math.min(1f, adjustedPercent));

        float rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f;
        this.mProgressBottom.setProgressRotation(rotation);
        this.setTargetOffsetTopAndBottomForBottom(targetY - mCurrentTargetOffsetBottom);


    }

    private void moveSpinner(float overscrollTop) {
        this.mProgress.setArrowEnabled(true);
        float originalDragPercent = overscrollTop / this.mTotalDragDistance;//原始拖动比例
        float dragPercent = Math.min(1.0F, Math.abs(originalDragPercent));//比例不能超过1
        float adjustedPercent = (float) Math.max((double) dragPercent - 0.4D, 0.0D) * 5.0F / 3.0F;//调整过的比例
        float extraOS = Math.abs(overscrollTop) - this.mTotalDragDistance;//额外的
        float slingshotDist = this.mCustomSlingshotDistance > 0 ? (float) this.mCustomSlingshotDistance : (float) (this.mUsingCustomStart ? this.mSpinnerOffsetEnd - this.mOriginalOffsetTop : this.mSpinnerOffsetEnd);
         float tensionSlingshotPercent = Math.max(0.0F, Math.min(extraOS, slingshotDist * 2.0F) / slingshotDist);
        float tensionPercent = (float) ((double) (tensionSlingshotPercent / 4.0F) - Math.pow((double) (tensionSlingshotPercent / 4.0F), 2.0D)) * 2.0F;
        float extraMove = slingshotDist * tensionPercent * 2.0F;
        int targetY = this.mOriginalOffsetTop + (int) (slingshotDist * dragPercent + extraMove);
        if (this.mCircleView.getVisibility() != 0) {
            this.mCircleView.setVisibility(0);
        }

        if (!this.mScale) {
            this.mCircleView.setScaleX(1.0F);
            this.mCircleView.setScaleY(1.0F);
        }

        if (this.mScale) {
            this.setAnimationProgress(Math.min(1.0F, overscrollTop / this.mTotalDragDistance));
        }

        if (overscrollTop < this.mTotalDragDistance) {
            if (this.mProgress.getAlpha() > 76 && !this.isAnimationRunning(this.mAlphaStartAnimation)) {
                this.startProgressAlphaStartAnimation();
            }
        } else if (this.mProgress.getAlpha() < 255 && !this.isAnimationRunning(this.mAlphaMaxAnimation)) {
            this.startProgressAlphaMaxAnimation();
        }

        float strokeStart = adjustedPercent * 0.8F;
        this.mProgress.setStartEndTrim(0.0F, Math.min(0.8F, strokeStart));
        this.mProgress.setArrowScale(Math.min(1.0F, adjustedPercent));
        float rotation = (-0.25F + 0.4F * adjustedPercent + tensionPercent * 2.0F) * 0.5F;
        this.mProgress.setProgressRotation(rotation);

        this.setTargetOffsetTopAndBottom(targetY - this.mCurrentTargetOffsetTop);
    }

    private void finishSpinner(float overscrollTop) {
        if (overscrollTop > this.mTotalDragDistance) {
            this.setRefreshing(true, true);
        } else {
            this.mRefreshing = false;
            this.mProgress.setStartEndTrim(0.0F, 0.0F);
            Animation.AnimationListener listener = null;
            if (!this.mScale) {

                listener = new Animation.AnimationListener() {
                    public void onAnimationStart(Animation animation) {
                    }

                    public void onAnimationEnd(Animation animation) {
                        if (!SwipeRefreshLayoutNew.this.mScale) {
                            SwipeRefreshLayoutNew.this.startScaleDownAnimation((Animation.AnimationListener) null);
                        }


                    }

                    public void onAnimationRepeat(Animation animation) {
                    }
                };
            }

            this.animateOffsetToStartPosition(this.mCurrentTargetOffsetTop, listener);
            this.mProgress.setArrowEnabled(false);
        }

    }

    /**
     * 结束下半部的spinner
     */
    private void finishSpinnerBottom(float overscrollTop) {//在小于mTotalDragDistance的时候处理的不好，会在中间停止

        if (overscrollTop > mTotalDragDistance) {
            this.setRefreshingBottom(true, true);
        } else {
            this.mRefreshingBottom = false;
            this.mProgressBottom.setStartEndTrim(0f, 0f);
            Animation.AnimationListener listener = null;
            if (!mScale) {
                listener = new Animation.AnimationListener() {

                    @Override
                    public void onAnimationStart(Animation animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        if (!SwipeRefreshLayoutNew.this.mScale) {
                            // startScaleDownAnimation(null);
                            SwipeRefreshLayoutNew.this.startScaleDownAnimationBottom(null);//倒着转
                        }
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }

                };
            }
            // animateOffsetToCorrectPositionBottom(mCurrentTargetOffsetBottom,listener);
            animateOffsetToStartPositionBottom(mCurrentTargetOffsetBottom, listener);
            mProgressBottom.setArrowEnabled(false);
        }
    }


    public boolean onTouchEvent(MotionEvent ev) {

        int action = ev.getActionMasked();
        if (this.mReturningToStart && action == 0) {
            this.mReturningToStart = false;
        }
        if (this.isEnabled() && !this.mReturningToStart && (!this.canChildScrollUp() || !this.canChildScrollDown()) && !this.mRefreshing && !this.mRefreshingBottom && !this.mNestedScrollInProgress) {
            float y;
            float overscrollTop, overscrollBottom;
            int pointerIndex;
            switch (action) {
                case 0:
                    this.mActivePointerId = ev.getPointerId(0);
                    this.mIsBeingDragged = false;
                    break;
                case 1:
                    pointerIndex = ev.findPointerIndex(this.mActivePointerId);
                    if (pointerIndex < 0) {
                        return false;
                    }

                    if (this.mIsBeingDragged) {
                        y = ev.getY(pointerIndex);
                        overscrollTop = (y - this.mInitialMotionY) * 0.5F;
                        overscrollBottom = (this.mInitialMotionYDown - y) * 0.5F;
                        this.mIsBeingDragged = false;
                        if(y>mInitialDownY){
                            if (!canChildScrollUp()) {
                                this.finishSpinner(overscrollTop);
                            }
                        }else  if(y<mInitialDownY){
                            if (!canChildScrollDown()) {
                                this.finishSpinnerBottom(overscrollBottom);
                            }
                        }
                    }

                    this.mActivePointerId = -1;
                    return false;
                case 2:
                    //canChildScrollUp为false代表顶部，canChildScrollDown为false代表底部
                    pointerIndex = ev.findPointerIndex(this.mActivePointerId);
                    if (pointerIndex < 0) {
                        return false;
                    }

                    y = ev.getY(pointerIndex);
                    this.startDragging(y);
                    if (this.mIsBeingDragged) {
                        overscrollTop = (y - this.mInitialMotionY) * 0.5F;
                        overscrollBottom = (this.mInitialMotionYDown - y) * 0.5F;
                        if (overscrollTop <= 0.0F) {
                            return false;
                        }
                        if (overscrollBottom <= 0.0F) {
                            return false;
                        }
                        if(y>mInitialDownY){
                            if (!canChildScrollUp()) {
                                this.moveSpinner(overscrollTop);
                            }
                        }else  if(y<mInitialDownY){
                            if (!canChildScrollDown()) {
                                this.moveBottomSpinner(overscrollBottom);
                            }
                        }


                    }
                    break;
                case 3:
                    return false;
                case 4:
                default:
                    break;
                case 5:
                    pointerIndex = ev.getActionIndex();
                    if (pointerIndex < 0) {
                        return false;
                    }

                    this.mActivePointerId = ev.getPointerId(pointerIndex);
                    break;
                case 6:
                    this.onSecondaryPointerUp(ev);
            }

            return true;
        } else {
            return false;
        }
    }

    private void startDragging(float y) {
        float yDiff = y - this.mInitialDownY;

        if (yDiff>0&&!canChildScrollUp()) {//当canChildScrollUp为false时，位于顶部，此时下拉出现加载动画
            if (yDiff > (float) this.mTouchSlop && !this.mIsBeingDragged) {
                this.mIsBeingDragged = true;
                this.mProgress.setAlpha(76);
            }
        }
        if (yDiff<0&&!canChildScrollDown()) {//当canChildScrollDown为false时，位于底部，此时上拉出现加载动画
            if ((-yDiff) > (float) this.mTouchSlop && !this.mIsBeingDragged) {
                this.mIsBeingDragged = true;
                this.mProgressBottom.setAlpha(76);
            }
        }


    }

    private void animateOffsetToCorrectPosition(int from, Animation.AnimationListener listener) {
        this.mFrom = from;

        this.mAnimateToCorrectPosition.reset();
        this.mAnimateToCorrectPosition.setDuration(200L);
        this.mAnimateToCorrectPosition.setInterpolator(this.mDecelerateInterpolator);
        if (listener != null) {
            this.mCircleView.setAnimationListener(listener);
        }

        this.mCircleView.clearAnimation();
        this.mCircleView.startAnimation(this.mAnimateToCorrectPosition);
    }

    /**
     * 启动关于mCircleView的动画mAnimateToCorrectPosition，相应的更改mFrom的值为
     * param:from
     */
    private void animateOffsetToCorrectPositionBottom(int from, Animation.AnimationListener listener) {
        this.mFrom = from;
        this.mAnimateToCorrectPositionBottom.reset();
        this.mAnimateToCorrectPositionBottom.setDuration(200);
        this.mAnimateToCorrectPositionBottom.setInterpolator(this.mDecelerateInterpolator);
        if (listener != null) {
            this.mCircleViewBottom.setAnimationListener(listener);
        }
        this.mCircleViewBottom.clearAnimation();
        this.mCircleViewBottom.startAnimation(this.mAnimateToCorrectPositionBottom);
    }

    private void animateOffsetToStartPosition(int from, Animation.AnimationListener listener) {
        if (this.mScale) {
            this.startScaleDownReturnToStartAnimation(from, listener);
        } else {
            this.mFrom = from;
            this.mAnimateToStartPosition.reset();
            this.mAnimateToStartPosition.setDuration(200L);
            this.mAnimateToStartPosition.setInterpolator(this.mDecelerateInterpolator);
            if (listener != null) {
                this.mCircleView.setAnimationListener(listener);
            }

            this.mCircleView.clearAnimation();
            this.mCircleView.startAnimation(this.mAnimateToStartPosition);
        }

    }

    private void animateOffsetToStartPositionBottom(int from, Animation.AnimationListener listener) {
        if (this.mScale) {
            // Scale the item back down
            this.startScaleDownReturnToStartAnimationBottom(from, listener);
        } else {
            this.mFrom = from;
            mAnimateToStartPositionBottom.reset();
            mAnimateToStartPositionBottom.setDuration(200);
            mAnimateToStartPositionBottom.setInterpolator(mDecelerateInterpolator);
            if (listener != null) {
                this.mCircleViewBottom.setAnimationListener(listener);
            }
            this.mCircleViewBottom.clearAnimation();
            this.mCircleViewBottom.startAnimation(mAnimateToStartPositionBottom);
        }
    }


    void moveToStart(float interpolatedTime) {
        int targetTop = this.mFrom + (int) ((float) (this.mOriginalOffsetTop - this.mFrom) * interpolatedTime);
        int offset = targetTop - this.mCircleView.getTop();
        this.setTargetOffsetTopAndBottom(offset);
    }

    /**
     * 回到顶部
     *
     * @param interpolatedTime 动画时间
     * @return 这里是根据当前位置 mFrom 回到 mOriginalOffsetTop
     */
    void moveToEnd(float interpolatedTime) {
        int targetTop = 0;
        targetTop = (this.mFrom + (int) ((this.mOriginalOffsetBottom - this.mFrom) * interpolatedTime));
        int offset = targetTop - this.mCircleViewBottom.getTop();
        this.setTargetOffsetTopAndBottomForBottom(offset);
    }

    private void startScaleDownReturnToStartAnimation(int from, Animation.AnimationListener listener) {
        this.mFrom = from;
        this.mStartingScale = this.mCircleView.getScaleX();
        this.mScaleDownToStartAnimation = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                float targetScale = SwipeRefreshLayoutNew.this.mStartingScale + -SwipeRefreshLayoutNew.this.mStartingScale * interpolatedTime;
                SwipeRefreshLayoutNew.this.setAnimationProgress(targetScale);
                SwipeRefreshLayoutNew.this.moveToStart(interpolatedTime);
            }
        };
        this.mScaleDownToStartAnimation.setDuration(150L);
        if (listener != null) {
            this.mCircleView.setAnimationListener(listener);
        }

        this.mCircleView.clearAnimation();
        this.mCircleView.startAnimation(this.mScaleDownToStartAnimation);
    }

    private void startScaleDownReturnToStartAnimationBottom(int from, Animation.AnimationListener listener) {
        this.mFrom = from;
        this.mStartingScale = this.mCircleViewBottom.getScaleX();
        this.mScaleDownToStartAnimation = new Animation() {
            public void applyTransformation(float interpolatedTime, Transformation t) {
                float targetScale = SwipeRefreshLayoutNew.this.mStartingScale + -SwipeRefreshLayoutNew.this.mStartingScale * interpolatedTime;
                SwipeRefreshLayoutNew.this.setAnimationProgressBottom(targetScale);
                SwipeRefreshLayoutNew.this.moveToEnd(interpolatedTime);
            }
        };
        this.mScaleDownToStartAnimation.setDuration(150L);
        if (listener != null) {
            this.mCircleViewBottom.setAnimationListener(listener);
        }

        this.mCircleViewBottom.clearAnimation();
        this.mCircleViewBottom.startAnimation(this.mScaleDownToStartAnimation);
    }

    void setTargetOffsetTopAndBottom(int offset) {
        this.mCircleView.bringToFront();
        ViewCompat.offsetTopAndBottom(this.mCircleView, offset);
        this.mCurrentTargetOffsetTop = this.mCircleView.getTop();
    }

    /**
     * 首先，提升circle的视图，然后将ciecle向上推offset个距离
     * 其中用到的是ViewCompat.offsetTopAndBottom(View,offset);正数向下 负数向上
     * 当requiresUpdate为true时，会进行整个的重绘，如果sdk小于11
     * <p>注意，每次移动的时候都会更新mCircleViewBottom</p>
     */
    void setTargetOffsetTopAndBottomForBottom(int offset) {
        this.mCircleViewBottom.bringToFront();//改变circle在俯视图中的位置即z坐标，将他提到最上面来
        //通过offset直接改变坐标，正数向下负数向上
        ViewCompat.offsetTopAndBottom(this.mCircleViewBottom, offset);
        this.mCurrentTargetOffsetBottom = this.mCircleViewBottom.getTop();
    }


    private void onSecondaryPointerUp(MotionEvent ev) {
        int pointerIndex = ev.getActionIndex();
        int pointerId = ev.getPointerId(pointerIndex);
        if (pointerId == this.mActivePointerId) {
            int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            this.mActivePointerId = ev.getPointerId(newPointerIndex);
        }

    }

    public interface OnChildScrollUpCallback {
        boolean canChildScrollUp(@NonNull SwipeRefreshLayoutNew var1, @Nullable View var2);
    }

    public interface OnRefreshListener {
        void onRefresh();
    }

    public interface OnBottomRefreshListener {
        void onBottomRefresh();
    }
}

